package jp.dodododo.aop.interceptors;

import java.lang.reflect.Method;

import jp.dodododo.aop.annotation.Enhance;

import org.aopalliance.intercept.Invocation;
import org.aopalliance.intercept.MethodInvocation;

/**
 * {@.en }
 * 
 * <br />
 * 
 * {@.ja シグネチャが同じ場合に、メソッドの実行を乗っ取るInterceptorです。}
 * 
 * @author Satoshi Kimura
 */
@Enhance(false)
public abstract class TakeOverInterceptor extends AbstractMethodInterceptor {

	private Object target;

	private Invocation invocation;

	/**
	 * 
	 * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
	 */
	public final Object invoke(final MethodInvocation invocation) throws Throwable {
		this.invocation = invocation;
		this.target = invocation.getThis();
		Method method = invocation.getMethod();
		Method takeOverMethod = null;
		try {
			takeOverMethod = this.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
			takeOverMethod.setAccessible(true);
			return takeOverMethod.invoke(this, invocation.getArguments());
		} catch (NoSuchMethodException e) {
			return invocation.proceed();
		}
	}

	protected Object getThis() {
		return target;
	}

	protected Invocation getInvocation() {
		return invocation;
	}

	protected static final TakeOverInterceptor getInstance() {
		throw new UnsupportedOperationException();
	}

}
